

#ifndef _UcExtensionModule_h
#define _UcExtensionModule_h

#if _MSC_VER >= 1000
#pragma once
#endif 

#include "zadesk.h"
#include "zacdocman.h"

class CUcExtensionModule {
public:
                CUcExtensionModule ();
                ~CUcExtensionModule ();

protected:
        BOOL    m_bAttached;
        HINSTANCE m_hDefaultResource;
        HINSTANCE m_hModuleResource;
#ifdef _ZSOFT_WINDOWS_
        AFX_EXTENSION_MODULE m_module;
#endif

public:
        BOOL    Attached ();
        HINSTANCE DefaultResourceInstance ();
        HINSTANCE ModuleResourceInstance ();

        BOOL    AttachInstance (HINSTANCE hInst);

        void    DetachInstance ();
};

inline CUcExtensionModule::CUcExtensionModule () :
    m_bAttached(FALSE),
    m_hDefaultResource(NULL),
    m_hModuleResource(NULL)
{
#ifdef _ZSOFT_WINDOWS_
    m_module.bInitialized = FALSE;
    m_module.hModule = NULL;
    m_module.hResource = NULL;
    m_module.pFirstSharedClass = NULL;
    m_module.pFirstSharedFactory = NULL;
#endif
}

inline CUcExtensionModule::~CUcExtensionModule ()
{
}

inline BOOL CUcExtensionModule::Attached ()
{
    return m_bAttached;
}

inline BOOL CUcExtensionModule::AttachInstance (HINSTANCE hInst)
{
    if (m_bAttached)
        return FALSE;
#ifdef _ZSOFT_WINDOWS_
    m_bAttached = AfxInitExtensionModule(m_module, hInst);
#else
    m_bAttached = true;
#endif
    if (m_bAttached) {
        m_hDefaultResource = AfxGetResourceHandle();
        m_hModuleResource = hInst;
#ifdef _ZSOFT_WINDOWS_
        new CDynLinkLibrary(m_module);
#endif
    }
    return m_bAttached;
}

inline HINSTANCE CUcExtensionModule::DefaultResourceInstance ()
{
    return m_hDefaultResource;
}

inline void CUcExtensionModule::DetachInstance ()
{
    if (m_bAttached) {
#ifdef _ZSOFT_WINDOWS_
        AfxTermExtensionModule(m_module);
#endif
        m_bAttached = FALSE;
    }
}

inline HINSTANCE CUcExtensionModule::ModuleResourceInstance ()
{
    return m_hModuleResource;
}

class CUcModuleResourceOverride {
public:
                    CUcModuleResourceOverride ();
                    CUcModuleResourceOverride (HINSTANCE hInst);
                    ~CUcModuleResourceOverride ();

private:
static  CUcExtensionModule& m_extensionModule;
};

inline CUcModuleResourceOverride::CUcModuleResourceOverride ()
{
    ucDocManager->pushResourceHandle(m_extensionModule.ModuleResourceInstance());
}

inline CUcModuleResourceOverride::CUcModuleResourceOverride (HINSTANCE hInst)
{
    ucDocManager->pushResourceHandle(hInst ? hInst : 
                                     m_extensionModule.ModuleResourceInstance());
}

inline CUcModuleResourceOverride::~CUcModuleResourceOverride ()
{
    ucDocManager->popResourceHandle();
}

#define UC_DECLARE_EXTENSION_MODULE(exm)        \
    extern CUcExtensionModule exm;

#define UC_IMPLEMENT_EXTENSION_MODULE(exm)      \
    CUcExtensionModule exm;                     \
    CUcExtensionModule& CUcModuleResourceOverride::m_extensionModule = exm;

#endif
